作者:手机用户282914901 | 来源:互联网 | 2023-09-09 10:21
篇首语:本文由编程笔记#小编为大家整理,主要介绍了Vuex状态管理机制相关的知识,希望对你有一定的参考价值。
状态管理机制
- vuex
- 什么是Vuex
- 使用Vuex管理数据优势
- vuex核心概念
- 安装与配置
- 通过 Vuex中的计算属性getters获取数据
- 操作Vuex中的数据
- modules模块化
- vuex强制开始命名空间
- 辅助函数mapState、mapGetters、mapActions、mapMutations
vuex
什么是Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享。如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。如果您的应用够简单,最好不要使用Vuex。
使用Vuex管理数据优势
-
能够在vuex中集中管理共享的数据,便于开发和后期进行维护
-
能够高效的实现组件之间的数据共享,提高开发效率
-
存储在vuex中的数据是响应式的,当数据发生改变时,页面中的视图也会同步更新
-
vuex中的数据操作可以在开发阶段通过开发调试工具来进行追踪,便于开发
-
如果说组件中数量过多,且公用的数据和数据操作也多,就考虑使用统一的数据管理工具。例如登录后都会用到用户的此状态
vuex核心概念
vuex对象中通过state来存储状态,除了state以外还有用来操作state中数据的方法集,以及当我们需要对state中的数据需要加工的方法集等等成员。
成员列表:
-
state 存放状态(全局状态数据) 必填项
-
mutations 对于state成员进行同步修改操作(调试工具)
-
getters 获取state中的数据,类似于组件中的计算属性
-
actions 进行异步操作,异步得到结果后通知mutation修改state成员
-
modules 模块化状态管理,多状态文件管理时使用 开发项目时多为多模块项目
-
在多模块vuex中会有配置 namespaced:true ->开启命名空间
首先,Vue组件如果调用某个VueX的方法过程中需要向后端请求时或者说出现异步操作时,需要dispatch VueX中actions的方法,以保证数据的同步。可以说,action的存在就是为了让mutations中的方法能在异步操作中起作用。
如果没有异步操作,那么我们就可以直接在组件内提交状态中的Mutations中自己编写的方法来达成对state成员的操作。不建议在组件中直接对state中的成员进行操作,这是因为直接修改(例如:this.$store.state.name = ‘hello’)的话不能被VueDevtools所监控到。最后被修改后的state成员会被渲染到组件的原位置当中去。
安装与配置
方案1:在使用vue-cli命令创建项目时,勾选上vuex选项,即安装上vuex插件(推荐)
方案2:通过后续的npm来进行安装
npm i -S vuex@3
建立store/index.js文件
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store(
state:
num:100
)
export default store;
然后在main.js中导入Vue配置项当中。
然后在各个组件devtools的vuex中,就可以看见这个数据。
this.$store.state.num
可以利用计算属性来完成对于在vuex中获取state数据的简写
组件中:
<h2>我从vuex中读取数据——————$store.state.num</h2>
<h2>我从vuex通过计算属性读取数据——————data</h2>
操作这个数据&#xff1a;
methods:
add()
this.$store.state.num&#43;&#43;
通过 Vuex中的计算属性getters获取数据
专门用于获取state状态中的数据&#xff0c;有缓存&#xff0c;只要依赖项不发生改变&#xff0c;那么他就读取缓存。
const store &#61; new Vuex.Store(
state:
num:100
,
getters:
getNum(state)
return state.num>103?"超过103":state.num;
)
使用&#xff1a;
<h2>我从vuex的getters中读取数据——————$store.getters.getNum</h2>
操作Vuex中的数据
同步操作mutations
mutations:
addNum(state,arg&#61;1)
state.num &#43;&#61; arg;
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
methods:
add()
this.$store.commit("addNum",2)
异步操作actions
actions:
async addDate(store,arg)
console.log(arg);
let data &#61; await get("/mock/data.json");
&#61;&#61;&#61;&#61;&#61;&#61;&#61;
通过dispath通知actions里执行那个异步方法&#xff1b;
methods:
addasync()
this.$store.dispatch("addDate","加油你是最棒的");
但是我们最终的目的是为了将异步得到的值&#xff0c;传给mutations做同步响应式处理&#xff0c;所以在通过commit通知mutations&#xff0c;执行相应的操作。
伪代码处理&#xff1a;
state:
data:
,
mutations:
addDATA(state,data)
state.data &#61; data;
,
actions:
async addDate(store,arg)
let data &#61; await get("/mock/data.json");
store.commit("addDATA",data);
mock假数据&#xff0c;我写nodejs服务器&#xff1b;15-mock模拟数据备份
modules模块化
模块化&#xff0c;把state数据拆分到不同的模块中(不同文件中)&#xff0c;把原来也在Vue.stroe实例配置中的代码&#xff0c;提取到不同的业务文件中。
export default
state:
num:100,
,
getters:
getNum(state)
return state.num;
,
mutations:,
actions:
import count from &#39;&#64;/store/modules/count.js&#39;
import data from &#39;&#64;/store/modules/data.js&#39;
export default
modules:
count,
data
命名空间就是这样的做法&#xff0c;将这个空间名放在组件中进行调用。
如果在组件中是&#xff1a;直接调用这个vux状态管理的数据的话&#xff0c;那就需要添加一个模块名或者空间名&#xff1a;
$store.state.count.num
this.$store.state.count.num
但是对于
getters、mutations、actions不会有影响
vuex强制开始命名空间
因为但虽然在不同的模块中&#xff0c;但是状态管理最终是添加在一起的&#xff0c;所以有方法有同名的话仍然会执行这个同名函数&#xff1a;为了避免这种错误&#xff0c;vuex开启了命名空间。
namespaced:true,
export default
namespaced:true,
state:
num:100,
,
getters:
getNum(state)
return state.num;
,
这样就对getters、mutations、actions三个起到空间作用。
需要加上空间名才能调用&#xff1a;
他在getNum之前加上了空间名&#xff1a;
<h2>我从vuex的getters中读取数据——————$store.getters["count/getNum"] </h2>
this.$store.getters["count/getNum"]
this.$store.commit("count/addNum", 2)
这样就不会发生冲突。
辅助函数mapState、mapGetters、mapActions、mapMutations
注&#xff1a;模块化后&#xff0c;开启了namespaced:true 配置后&#xff0c;注意方法的调用有2个参数
在没有开启命名空间时的辅助函数写法
mapState返回的是一个对象&#xff0c;对象里面有一个方法。
computed:
...mapState(
data:state&#61;>state.count.num
)
...mapState(["count"])
数组中的元素&#xff0c;如果有模块化&#xff0c;则为modules中key的名称。
......mapState(["count"])
返回值是一个&#xff1a; "num": 100 对象
如果要用它的话&#xff1a;
<h2>我从vuex中读取数据—————— $store.state.count.num </h2>
<h2>我从vuex通过计算属性读取数据—————— data </h2>
<h2>我从vuex的getters中读取数据——————$store.getters["getNum"] </h2>
<h2>我从vuex的mapState中读取数据——————count.num </h2>
有命名空间的写法